`ifndef LPU_INTF_SVH
`define LPU_INTF_SVH

interface lpu_is_mxu_instr_if (
    input clk,
    input rst_n
);
    logic              vld;
    instr_mxu_matmul_t pld;
    logic              rdy;
    modport in(input vld, input pld, output rdy);
    modport out(output vld, output pld, input rdy);
endinterface

interface done_if (
    input clk,
    input rst_n
);
    logic    vld;
    uint16_t instr_idx;
    modport in(input vld, input instr_idx);
    modport out(output vld, output instr_idx);
endinterface

interface ub_rd_req_if (
    input clk,
    input rst_n
);
    logic           vld;
    ub_addr_t       ub_addr;
    logic     [1:0] src;  // 00: normal read, 01: atomic read, 10: ldma read
    logic           rdy;
    modport in(input vld, input ub_addr, input src, output rdy);
    modport out(output vld, output ub_addr, output src, input rdy);
endinterface

typedef struct packed {
    ub_addr_t            ub_addr;
    bf16_t [`N0*`K0-1:0] dat;
    logic [`N0*`K0-1:0]  msk;
    logic [1:0]          atomic_mode;
} gdma_ub_wr_req_s;

interface gdma_ub_wr_req_if (
    input clk,
    input rst_n
);
    logic            vld;
    gdma_ub_wr_req_s pld;
    logic            rdy;
    modport in(input vld, input pld, output rdy);
    modport out(output vld, output pld, input rdy);
endinterface

typedef struct packed {
    ub_addr_t               ub_addr;
    bf16_t [`P_ARU*`N0-1:0] dat;
    logic [`P_ARU*`N0-1:0]  msk;
    logic [1:0]             atomic_mode;
} aru_ub_wr_req_s;

interface aru_ub_wr_req_if (
    input clk,
    input rst_n
);
    logic           vld;
    aru_ub_wr_req_s pld;
    logic           rdy;
    modport in(input vld, input pld, output rdy);
    modport out(output vld, output pld, input rdy);
endinterface

interface lmb_rd_req_if (
    input clk,
    input rst_n
);
    logic        vld;
    logic [15:0] lmb_addr;
    logic        rdy;
    modport in(input vld, input lmb_addr, output rdy);
    modport out(output vld, output lmb_addr, input rdy);
endinterface

interface rmb_rd_req_if (
    input clk,
    input rst_n
);
    logic        vld;
    logic [15:0] rmb_addr;
    logic        rdy;
    modport in(input vld, input rmb_addr, output rdy);
    modport out(output vld, output rmb_addr, input rdy);
endinterface

interface pmb_rd_req_if (
    input clk,
    input rst_n
);
    logic        vld;
    logic [15:0] pmb_addr;
    logic        rdy;
    modport in(input vld, input pmb_addr, output rdy);
    modport out(output vld, output pmb_addr, input rdy);
endinterface

interface psb_rd_req_if (
    input clk,
    input rst_n
);
    logic        vld;
    logic [23:0] psb_addr;
    logic        rdy;
    modport in(input vld, input psb_addr, output rdy);
    modport out(output vld, output psb_addr, input rdy);
endinterface

interface psb_wr_req_if (
    input clk,
    input rst_n
);
    logic                     vld;
    logic  [   23:0]          psb_addr;
    fp32_t [`M0-1:0][`N0-1:0] dat;
    logic  [`M0-1:0][`N0-1:0] msk;
    logic                     rdy;
    modport in(input vld, input psb_addr, input dat, input msk, output rdy);
    modport out(output vld, output psb_addr, output dat, output msk, input rdy);
endinterface

interface lmb_dat_if (
    input clk,
    input rst_n
);
    logic                vld;
    pack_16B_t [`M0-1:0] dat;
    logic                rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface

interface rmb_dat_if (
    input clk,
    input rst_n
);
    logic                vld;
    pack_16B_t [`N0-1:0] dat;
    logic                rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface

interface pmb_dat_if (
    input clk,
    input rst_n
);
    logic            vld;
    fp32_t [`N0-1:0] dat;
    logic            rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface

interface aru_ub_dat_if (
    input clk,
    input rst_n
);
    logic                        vld;
    bf16_t [`P_ARU-1:0][`N0-1:0] dat;
    logic                        rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface

interface ldma_ub_dat_if (
    input clk,
    input rst_n
);
    logic  vld;
    bf16_t dat [`N0-1:0][`K0-1:0];
    logic  rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface

interface mxu_psb_dat_if (
    input clk,
    input rst_n
);
    logic                     vld;
    fp32_t [`M0-1:0][`N0-1:0] dat;
    logic                     rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface

interface aru_psb_dat_if (
    input clk,
    input rst_n
);
    logic                        vld;
    fp32_t [`P_ARU-1:0][`N0-1:0] dat;
    logic                        rdy;
    modport in(input vld, input dat, output rdy);
    modport out(output vld, output dat, input rdy);
endinterface
`endif
